/* Copyright 2012 Tobias Marschall
 * 
 * This file is part of CLEVER.
 * 
 * CLEVER is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * CLEVER is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with CLEVER.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <iostream>
#include <fstream>

#include <boost/program_options.hpp>

#include "HistogramBasedDistribution.h"
#include "ReadSetGenericTester.h"
#include "VersionInfo.h"

using namespace std;
using namespace boost;
namespace po = boost::program_options;

void usage(const char* name, const po::options_description& options_desc) {
	cerr << "Usage: " << name << " [options] <distribution-file>" << endl;
	cerr << endl;
	cerr << "<distribution-file> file with internal segment length distribution" << endl;
	cerr << "                    as computed by insert-length-histogram." << endl;
	cerr << endl;
	cerr << "Outputs distributions of sums of internal segment sizes of" << endl;
	cerr << "n independently drawn alignments for n=1..N, where N can be" << endl;
	cerr << "set using option -N. Output is written to stdout." << endl;
	cerr << endl;
	cerr << options_desc << endl;
	exit(1);
}

int main(int argc, char* argv[]) {
	VersionInfo::checkAndPrintVersion("precompute-distributions", cerr);
	string commandline = VersionInfo::commandline(argc, argv);

	// PARAMETERS
	int max_count;

	po::options_description options_desc("Allowed options");
	options_desc.add_options()
		("max_count,N", po::value<int>(&max_count)->default_value(500), "Value up to which distributions are to be computed.")
	;
	
	if (argc<2) {
		usage(argv[0], options_desc);
	}
	string distribution_filename(argv[argc-1]);
	argc -= 1;

	po::variables_map options;
	try {
		po::store(po::parse_command_line(argc, argv, options_desc), options);
		po::notify(options);
	} catch(std::exception& e) {
		cerr << "error: " << e.what() << "\n";
		return 1;
	}
	cerr << "Commandline: " << commandline << endl;

	HistogramBasedDistribution* insert_length_distribution = 0;
	try {
		insert_length_distribution = new HistogramBasedDistribution(distribution_filename);
	} catch (std::runtime_error& e) {
		cerr << "Error: " << e.what() << endl;
		return 1;
	}
	ReadSetGenericTester tester(*insert_length_distribution);
	for (int i=2; i<=max_count; ++i) {
		cerr << "Computing distribution for n=" << i << endl;
		tester.cacheDistributions(i);
	}
	tester.writeCachedDistributions(cout);
	delete insert_length_distribution;
	return 0;
}
